﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Core.Cache;
using Core.SupportEntities;
using MSSqlDataBase;
using Core.Constants;

namespace Infrastructure.Managers
{
    public class CacheManager : BaseManager
    {
        public static List<CacheTable> _cacheTable;

        public static List<CacheTable> CacheTable
        {
            get
            {
                if (_cacheTable == null)
                    _cacheTable = new CacheManager().GetCacheTable();
                return _cacheTable;
            }
            private set
            {
                _cacheTable = value;
            }
        }

        public List<CacheTable> GetCacheTable()
        {
            List<CacheTable> cacheTable = _cache.Get(ConstantsCache.STR_CACHETABLE) as List<CacheTable>;

            if (cacheTable == null)
            {
                cacheTable = _dbContext.Get<CacheTable>().ToList();

                if (cacheTable.Any())
                {
                    _cache.Set(ConstantsCache.STR_CACHETABLE, cacheTable, 30);
                }
            }

            return cacheTable;
        }

        public List<CacheTable> RefreshCacheTable()
        {
            var cacheTables = GetCacheTable();
            using(PageManager pageManager = new PageManager())
            {
                var pageGroups = pageManager.GetSitePageGroupsWithPagesAndContentBlocks();
                foreach (var pageGroup in pageGroups)
                {
                    foreach (var sitePageDefinition in pageGroup.SitePageDefinition)
                    {
                        var existedCachePageEntry = cacheTables.SingleOrDefault(x => x.Controller == pageGroup.GroupName && x.Action == sitePageDefinition.InternalName);
                        if (existedCachePageEntry == null)
                        {
                            _dbContext.Insert<CacheTable>(new CacheTable() { Controller = pageGroup.GroupName, Action = sitePageDefinition.InternalName });
                        }
                    }
                }
            _dbContext.Save();
        }
            ClearAllCache();
            return GetCacheTable();
        }

        public string UpdateCacheTable(List<CacheTable> cacheTableList)
        {
            foreach (var cacheTable in cacheTableList)
            {
                var existedCacheTable = _dbContext.Get<CacheTable>(x => x.Id == cacheTable.Id).SingleOrDefault();
                existedCacheTable.Duration = cacheTable.Duration;
                existedCacheTable.IsEtag = cacheTable.IsEtag;
                existedCacheTable.IsGzip = cacheTable.IsGzip;
                existedCacheTable.CachePolicy = cacheTable.CachePolicy;
                existedCacheTable.IsEnabled = cacheTable.IsEnabled;               
            }

            var count = _dbContext.Save();
            ResetCacheDataTable();
            return String.Format("Success! {0} database changes saved.", count);
        }

        public string ClearAllCache()
        {
            _cache.CrearCache();
            CacheTable = null;
            return "Success!";
        }

        private void ResetCacheDataTable()
        {
            _cache.Invalidate(ConstantsCache.STR_CACHETABLE);
            CacheTable = null;
        }
    }
}
